<template>
	<view v-if="show" :class="[ 'popup-wrapper', `popup-wrapper--${direction}`, `is-${status ? 'open' : 'close'}` ]" @touchmove.stop.prevent>
		<view class="popup-modal" :style="{backgroundColor: modalBackgroundColor}" @tap="modalClose"></view>
		<view class="popup" :style="{ height, width, background, borderRadius: $xl.parseUnit(borderRadius) }">
			<xl-status-bar v-if="statusBar && props.direction !== 'bottom' && props.direction !== 'center'"></xl-status-bar>
			<view class="popup-container" :style="{ padding: $xl.parseUnit(padding) }">
				<slot></slot>
			</view>
		</view>
	</view>
</template>

<script setup>
	import propsData from './props.js'
	const props = defineProps(propsData)
	
	import { ref, computed, watch } from 'vue'
	defineExpose({ open, close })
	const emits = defineEmits(['update:modelValue', 'open', 'opened', 'close', 'closed'])
	
	const height = computed(()=>{
		switch (props.direction) {
			case "top":
			case "bottom":
				return uni.$xl.parseUnit(props.size);
			case "left":
			case "right":
				return "100%";
			case "center": 
				return 'auto'
		}
	})
	const width = computed(()=>{
		switch (props.direction) {
			case "top":
			case "bottom":
				return "100%";
			case "left":
			case "right":
			case "center":
				return uni.$xl.parseUnit(props.size);
		}
	})
	
	
	let show = ref(false)
	let status = ref(false)
	watch( () => props.modelValue, (newValue, oldValue) => {
		if (newValue) open() 
		else close()
	}, { immediate: true })
	
	// 动画状态计时器
	
	var timer = null
	function open() {
		if (!show.value) {
			// 显示内容
			show.value = true;
			// 触发父元素改变visible值
			emits("update:modelValue", true);
			emits("open");
			clearTimeout(timer);
			timer = setTimeout(() => {
				// 开始动画
				status.value = true;
				// 等待动画结束
				timer = setTimeout(() => {
					emits("opened");
				}, 350);
			}, 50);
		}
	}
	function close() {
		if (status.value) {
			const done = () => {
				// 关闭动画
				status.value = false;
				emits("close");

				clearTimeout(timer);
				timer = setTimeout(() => {
					// 隐藏内容
					show.value = false;
					emits("update:modelValue", false);
					emits("closed");
				}, 300);
			};

			if (props.beforeClose) {
				props.beforeClose(done);
			} else {
				done();
			}
		}
	}
	
	function modalClose() {
		if (!props.modalClose) {
			return false;
		}
		close();
	}
</script>

<style lang="scss" scoped>
	.popup-wrapper {
		position: fixed;
		bottom: 0;
		top: 0;
		left: 0;
		right: 0;
		z-index: v-bind(zIndex);
		opacity: 0;
		transition: all 0.3s;
		pointer-events: none;
	
		&.is-open {
			opacity: 1;
			pointer-events: auto;
	
			.popup {
				transition: all 0.4s;
				transform: translate(0, 0);
			}
		}
	
		&::after {
			content: "";
			display: inline-block;
			height: 100%;
			width: 0;
			vertical-align: middle;
		}
	
		.popup-modal {
			// height: 100%;
			// width: 100%;
			position: absolute;
			top: 0rpx;
			bottom: 0;
			left: 0;
			right: 0;
		}
	
		.popup {
			display: flex;
			flex-direction: column;
			background-color: #fff;
			position: absolute;
			transition: all 0.3s;
			box-sizing: border-box;
	
			&-container {
				height: 100%;
			}
		}
	
		&--left {
			.popup {
				transform: translateX(-100%);
				top: 0;
				left: 0;
			}
		}
	
		&--right {
			.popup {
				transform: translateX(100%);
				right: 0;
				top: 0;
			}
		}
	
		&--top {
			.popup {
				transform: translateY(-100%);
				left: 0;
				top: 0;
			}
		}
	
		&--bottom {
			.popup {
				transform: translateY(100%);
				left: 0;
				bottom: 0;
			}
		}
	
		&--center {
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
	
			.popup {
				transform: scale(1.3);
			}
		}
	
		&--top,
		&--left,
		&--right {
			.popup {
				/* #ifdef H5 */
				// padding-top: 44px;
				/* #endif */
	
				/* #ifndef H5 */
				padding-top: env(safe-area-inset-top);
				/* #endif */
			}
		}
	
		&--left,
		&--right,
		&--bottom {
			.popup {
				padding-bottom: env(safe-area-inset-bottom);
			}
		}
	}
	
</style>
